package TMS.src;

import java.io.*;
import java.util.*;

public class Order {
    public static int numOfOrder = 0;
    private String shopId;//店铺
    private int quantity;//数量
    private User master;//顾客
    private int orderStatus;//0/1/2分别对应三种状态待处理，已取消，finish
    private String orderId;//O-num
    private Commodity commodity;

    public Order(Commodity commodity, int quantity) {
        numOfOrder++;
        this.orderId = "O-" + numOfOrder;
        this.shopId = commodity.getShopId();
        this.commodity = commodity;
        this.quantity = quantity;
        this.orderStatus = 0;//待处理
        this.master = Const.current_user;
    }

    public Order() {
    }

    void setCommodity(Commodity commodity) {
        this.commodity = commodity;
    }

    void setOrderId(String id) {
        this.orderId = id;
    }

    void setMaster(User customer) {
        this.master = customer;
    }

    void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    void setOrderStatus(int status) {
        this.orderStatus = status;
    }

    Commodity getCommodity() {
        return this.commodity;
    }

    String getOrderId() {
        return this.orderId;
    }

    User getMaster() {
        return this.master;
    }

    int getQuantity() {
        return this.quantity;
    }

    int getOrderStatus() {
        return this.orderStatus;
    }

    Map<String, Order> sortListOrder(Map<String, Order> map) {
        //HashMap无序；LinkedHashMap有序）
        LinkedHashMap<String, Order> linkedHashMap = new LinkedHashMap<>();
        Set<Map.Entry<String, Order>> entrySet = map.entrySet();
        List<Map.Entry<String, Order>> list = new ArrayList<>(entrySet);
        list.sort(Comparator.comparingInt(o -> Integer.parseInt(o.getKey().substring(2))));
        list.forEach(item -> linkedHashMap.put(item.getKey(), item.getValue()));
        return linkedHashMap;
    }

    public String CancelOrder(String[] cmd) {//一个参数，订单编号
        User current_user = Const.current_user;
        if (cmd.length != 2)
            return "Illegal argument count";
        else if (current_user == null)
            return "Please log in first";
        else if (!current_user.getIdentity().equals("Customer"))
            return "Permission denied";

        String orderId = cmd[1];
        boolean orderId_illegal = !orderId.matches("^O-[1-9]\\d*$");
        boolean order_not_existed = true;
        if (Const.allOrder_existed.containsKey(orderId))
            if (Const.allOrder_existed.get(orderId).getMaster().equals(current_user))
                order_not_existed = false;

        if (orderId_illegal)
            return "Illegal order id";
        else if (order_not_existed)
            return "Order id not exists";

        boolean order_already_canceled = Const.allOrder_existed.get(orderId).getOrderStatus() == 1;
        boolean order_already_finished = Const.allOrder_existed.get(orderId).getOrderStatus() == 2;
        if (order_already_canceled)
            return "Order already canceled";
        else if (order_already_finished)
            return "Order already finished";
        //究竟是什么时候减少商品？？现在把减少的商品放回去
        Commodity commodity = Const.allOrder_existed.get(orderId).getCommodity();
        commodity.setCommodityNum(commodity.getCommodityNum() + Const.allOrder_existed.get(orderId).getQuantity());
        Const.allOrder_existed.get(orderId).setOrderStatus(1);

        return "Cancel order success";
    }

    public String FinishOrder(String[] cmd) {//一个参数，订单编号
        User current_user = Const.current_user;
        if (cmd.length != 2)
            return "Illegal argument count";
        else if (current_user == null)
            return "Please log in first";
        else if (!current_user.getIdentity().equals("Customer"))
            return "Permission denied";

        String orderId = cmd[1];
        boolean orderId_illegal = !orderId.matches("^O-[1-9]\\d*$");
        boolean order_not_existed = true;

        if (Const.allOrder_existed.containsKey(orderId))
            if (Const.allOrder_existed.get(orderId).getMaster().equals(current_user))
                order_not_existed = false;

        if (orderId_illegal)
            return "Illegal order id";
        else if (order_not_existed)
            return "Order id not exists";

        boolean order_already_canceled = Const.allOrder_existed.get(orderId).getOrderStatus() == 1;
        boolean order_already_finished = Const.allOrder_existed.get(orderId).getOrderStatus() == 2;
        if (order_already_canceled)
            return "Order already canceled";
        else if (order_already_finished)
            return "Order already finished";

        Const.allOrder_existed.get(orderId).setOrderStatus(2);
        return "Finish order success";
    }

    public String listOrder(String[] cmd) {//一个可选参数，店铺编号
        User current_user = Const.current_user;
        if (cmd.length > 2)
            return "Illegal argument count";
        else if (current_user == null)
            return "Please log in first";

        Map<String, Order> orderMap = new HashMap<>();
        if (cmd.length == 1) {
            if (current_user.getIdentity().equals("Administrator")) {
                for (Order order : Const.allOrder_existed.values()) {
                    orderMap.put(order.getOrderId(), order);
                }
            } else if (current_user.getIdentity().equals("Merchant")) {
                for (Order order : Const.allOrder_existed.values()) {
                    if (order.getCommodity().getMaster().equals(current_user))
                        orderMap.put(order.getOrderId(), order);
                }
            } else if (current_user.getIdentity().equals("Customer")) {
                for (Order order : Const.allOrder_existed.values()) {
                    if (order.getMaster().equals(current_user))
                        orderMap.put(order.getOrderId(), order);
                }
            }
        } else if (cmd.length == 2) {
            String shopId = cmd[1];
            if (current_user.getIdentity().equals("Customer"))
                return "Permission denied";

            boolean shopId_illegal = !shopId.matches("S-[1-9]\\d*");
            if (shopId_illegal)
                return "Illegal shop id";

            boolean shop_not_existed = true;
            if (Const.allShop_existed.containsKey(shopId))//存在
                if (Const.allShop_existed.get(shopId).getMaster().equals(current_user)||current_user.getIdentity().equals("Administrator"))
                    shop_not_existed = false;
            if (shop_not_existed)
                return "Shop id not exists";
            for (Order order : Const.allOrder_existed.values()) {
                if (order.getCommodity().getShopId().equals((shopId)))
                    orderMap.put(order.getOrderId(), order);
            }
        }

        if (orderMap.isEmpty())
            return "Order not exists";
        else {
            Map<String, Order> sortedOrderMap = sortListOrder(orderMap);
            for (Order order : sortedOrderMap.values()) {
                String status = new String[]{"pending", "canceled", "finished"}[order.getOrderStatus()];
                System.out.println(order.getOrderId() + ": " + order.getCommodity().getShopId() + " " + order.getCommodity().getCommodityId() + " " + order.getQuantity() + " " + String.format("%.2f", order.getCommodity().getCommodityPrice() * order.getQuantity()) + "yuan " + status);
            }
            return null;
        }
    }

    public void WriteFile(String contents, String fileName, boolean append) throws IOException {
        String path = fileName.substring(0, fileName.lastIndexOf("/"));
        File file = new File(fileName);//我们在该类的位置创建一个新文件
        File folder = new File(path);
        if (!folder.exists() && !folder.isDirectory())//文件夹不存存在就新建
            folder.mkdirs();
        if (!file.exists()) //不存在就新建文件
            try {
                file.createNewFile();
            } catch (IOException e) {
                System.out.println("File operation failed");
                //e.printStackTrace();
            }
        FileWriter writer = null;
        try {
            writer = new FileWriter(file, append);
            writer.append(contents);
            writer.flush();
        } catch (IOException e) {
            System.out.println("File operation failed");
            //e.printStackTrace();
        } finally {
            if (null != writer)
                writer.close();
        }
    }

    public String GetFile(String path) throws IOException {
        File file = new File(path);
        BufferedReader br = new BufferedReader(new FileReader(file));
        StringBuilder out = new StringBuilder();
        String line = null;
        try {
            while ((line = br.readLine()) != null) {
                //System.out.println(line);
                out.append(line).append("\n");
            }
            br.close();
        } catch (IOException e) {
            System.out.println("File operation failed");
            return null;
        }
        return out.toString();
    }

    public String ExportMerchantOrder(String[] cmd) throws IOException {//文件操作
        User current_user = Const.current_user;

        if (cmd.length == 1) {//打印并保存当前用户（商家order信息)
            if (current_user == null)
                return "Please log in first";
            else if (!current_user.getIdentity().equals("Merchant"))
                return "Permission denied";

            boolean order_not_exists = true;
            Map<String, Order> orderMap = new HashMap<>();
            for (Order order : Const.allOrder_existed.values()) {
                if (order.getCommodity().getMaster().equals(current_user)) {//当前商家有订单
                    orderMap.put(order.getOrderId(), order);
                    order_not_exists = false;
                }
            }
            if (order_not_exists)
                return "Order not exists";

            Map<String, Order> sortedOrderMap = sortListOrder(orderMap);//排序
            StringBuilder info = new StringBuilder();
            for (Order order : sortedOrderMap.values()) {
                String status = new String[]{"pending", "canceled", "finished"}[order.getOrderStatus()];
                String out = order.getOrderId() + ": " + order.getCommodity().getShopId() + " " + order.getCommodity().getCommodityId() + " " + order.getQuantity() + " " + String.format("%.2f", order.getCommodity().getCommodityPrice() * order.getQuantity()) + "yuan " + status;
                System.out.println(out);
                info.append(out).append("\n");
            }
            String path = "./data/order/";
            WriteFile(info.toString(), path + current_user.getCard_number() + ".txt", false);

        } else if (cmd.length == 2) {//参数为账号
            String card_number = cmd[1];
            if (card_number.equals(">") || card_number.equals(">>"))
                return "Please input the redirect path";
            else if (current_user == null)
                return "Please log in first";
            else if (!current_user.getIdentity().equals("Administrator"))
                return "Permission denied";

            boolean card_number_illegal = Gadget.check_user_card_illegal(card_number);
            if (card_number_illegal)
                return "Illegal Kakafee number";
            boolean card_not_existed = !Const.user_existed.containsKey(card_number);
            if (card_not_existed)
                return "Kakafee number not exists";
            boolean card_not_merchant = !Const.user_existed.get(card_number).getIdentity().equals("Merchant");
            if (card_not_merchant)
                return "Kakafee number does not belong to a Merchant";

            boolean order_not_existed = true;
            Map<String, Order> orderMap = new HashMap<>();
            for (Order order : Const.allOrder_existed.values()) {
                if (order.getCommodity().getMaster().getCard_number().equals(card_number)) {
                    order_not_existed = false;
                    orderMap.put(order.getOrderId(), order);
                }
            }
            if (order_not_existed)
                return "Order not exists";

            Map<String, Order> sortedOrderMap = sortListOrder(orderMap);//排序
            StringBuilder info = new StringBuilder();
            for (Order order : sortedOrderMap.values()) {
                String status = new String[]{"pending", "canceled", "finished"}[order.getOrderStatus()];
                String out = order.getOrderId() + ": " + order.getCommodity().getShopId() + " " + order.getCommodity().getCommodityId() + " " + order.getQuantity() + " " + String.format("%.2f", order.getCommodity().getCommodityPrice() * order.getQuantity()) + "yuan " + status;
                System.out.println(out);
                info.append(out).append("\n");
            }
            String path = "./data/order/";
            WriteFile(info.toString(), path + card_number + ".txt", false);

        } else if (cmd.length > 2) {//两个参数,重定向符号+路径,不打印只保存
            String symbol = cmd[1];
            String path;
            String rePath;
            if (cmd[2].charAt(0) == '.')//已经有 ./ 了
                rePath = "./data/" + cmd[2].substring(2);
            else
                rePath = "./data/" + cmd[2];

            if ((!symbol.equals(">")) && (!symbol.equals(">>")))
                return "Illegal argument count";
            else if (!rePath.matches("^[^*<>?|\"]*$"))
                return "Illegal redirect path";
            else if (cmd.length > 4) {
                WriteFile("Illegal argument count\n", rePath, symbol.equals(">>"));
                return null;
            }
            else if (current_user == null) {
                WriteFile("Please log in first\n", rePath, symbol.equals(">>"));
                return null;
            }

            //下面开始根据身份分支输出,此时控制台无输出，信息定向到rePath
            switch (current_user.getIdentity()) {
                case "Customer" -> {
                    WriteFile("Permission denied\n", rePath, symbol.equals(">>"));
                    return null;
                }
                case "Merchant" -> {
                    path = "./data/order/" + current_user.getCard_number() + ".txt";
                    if (cmd.length == 4) {
                        WriteFile("Permission denied\n", rePath, symbol.equals(">>"));
                        return null;
                    } else if (rePath.equals(path)) {
                        System.out.println("The save path is the same as the redirect path");
                        return null;
                    }

                    boolean order_not_existed = true;
                    Map<String, Order> orderMap = new HashMap<>();
                    for (Order order : Const.allOrder_existed.values()) {
                        if (order.getCommodity().getMaster().equals(current_user)) {
                            order_not_existed = false;
                            orderMap.put(order.getOrderId(), order);
                        }
                    }
                    if (order_not_existed) {
                        WriteFile( "Order not exists",rePath, symbol.equals(">>"));
                        return null;
                    }

                    Map<String, Order> sortedOrderMap = sortListOrder(orderMap);//排序
                    StringBuilder info = new StringBuilder();
                    for (Order order : sortedOrderMap.values()) {
                        String status = new String[]{"pending", "canceled", "finished"}[order.getOrderStatus()];
                        String out = order.getOrderId() + ": " + order.getCommodity().getShopId() + " " + order.getCommodity().getCommodityId() + " " + order.getQuantity() + " " + String.format("%.2f", order.getCommodity().getCommodityPrice() * order.getQuantity()) + "yuan " + status;
                        //System.out.println(out);//不需要打印
                        info.append(out).append("\n");
                    }
                    WriteFile(info.toString(), rePath, symbol.equals(">>"));
                    WriteFile(info.toString(), path, false);
                }
                case "Administrator" -> {
                    if (cmd.length == 3) {
                        WriteFile("Permission denied\n", rePath, symbol.equals(">>"));
                        return null;
                    }
                    String card_number = cmd[3];
                    path = "./data/order/" + card_number + ".txt";
                    if (Gadget.check_user_card_illegal(card_number)) {
                        WriteFile("Illegal Kakafee number\n", rePath, symbol.equals(">>"));
                        return null;
                    }
                    boolean card_not_existed = !Const.user_existed.containsKey(card_number);
                    if (card_not_existed) {
                        WriteFile("Kakafee number not exists\n", rePath, symbol.equals(">>"));
                        return null;
                    }
                    boolean card_not_merchant = !Const.user_existed.get(card_number).getIdentity().equals("Merchant");
                    if (card_not_merchant) {
                        WriteFile("Kakafee number does not belong to a Merchant\n", rePath, symbol.equals(">>"));
                        return null;
                    }

                    if (rePath.equals(path)) {
                        System.out.println("The save path is the same as the redirect path");
                        return null;
                    }
                    boolean order_not_existed = true;
                    Map<String, Order> orderMap = new HashMap<>();
                    for (Order order : Const.allOrder_existed.values()) {
                        if (order.getCommodity().getMaster().getCard_number().equals(card_number)) {
                            order_not_existed = false;
                            orderMap.put(order.getOrderId(), order);
                        }
                    }
                    if (order_not_existed) {
                        WriteFile( "Order not exists",rePath, symbol.equals(">>"));
                        return null;
                    }
                    Map<String, Order> sortedOrderMap = sortListOrder(orderMap);//排序
                    StringBuilder info = new StringBuilder();
                    for (Order order : sortedOrderMap.values()) {
                        String status = new String[]{"pending", "canceled", "finished"}[order.getOrderStatus()];
                        String out = order.getOrderId() + ": " + order.getCommodity().getShopId() + " " + order.getCommodity().getCommodityId() + " " + order.getQuantity() + " " + String.format("%.2f", order.getCommodity().getCommodityPrice() * order.getQuantity()) + "yuan " + status;
                        //System.out.println(out);
                        info.append(out).append("\n");
                    }
                    WriteFile(info.toString(), rePath, symbol.equals(">>"));
                    WriteFile(info.toString(), path, false);
                }
            }
        }
        return null;
    }

    public String OpenFile(String[] cmd) throws IOException {//文件操作
        User current_user = Const.current_user;
        if (cmd.length > 4 || cmd.length == 1)
            return "Illegal argument count";
        else if (current_user == null)
            return "Please log in first";

        String symbol;
        String path;
        String rePath;
        if (cmd.length == 2) {//一参数
            path = cmd[1];
            if (path.equals("<"))
                return "Please input the path to open the file";
            if (!path.matches("^[^*<>?|\"]*$"))
                return "Illegal path";
            if (cmd[1].charAt(0) == '.')//已经有 ./ 了
                path = "./data/" + cmd[1].substring(2);
            else
                path = "./data/" + cmd[1];

            File file = new File(path);
            if ((!file.exists()) || file.isDirectory())
                return "File not exists";
            String out = GetFile(path);
            if (out == null)
                return null;
            else
                System.out.print(out);//getFile已经每句换行了，这里就不换行了

        } else if (cmd.length == 3) {
            symbol = cmd[1];
            rePath = cmd[2];
            if (!symbol.equals("<"))
                return "Illegal redirector";
            if (!rePath.matches("^[^*<>?|\"]*$"))
                return "Illegal redirect path";
            if (cmd[2].charAt(0) == '.')//已经有 ./ 了
                rePath = "./data/" + cmd[2].substring(2);
            else
                rePath = "./data/" + cmd[2];

            File file = new File(rePath);
            if ((!file.exists()) || file.isDirectory())
                return "File not exists";
            String out = GetFile(rePath);
            if (out == null)
                return null;
            else
                System.out.print(out);//getFile已经每句换行了，这里就不换行了

        } else if (cmd.length == 4) {
            path = cmd[1];
            symbol = cmd[2];
            rePath = cmd[3];
            boolean rePath_illegal = false;
            if (!symbol.equals("<"))
                return "Illegal redirector";
            if (!rePath.matches("^[^*<>?|\"]*$"))
                rePath_illegal = true;

            if (cmd[3].charAt(0) == '.')//已经有 ./ 了
                rePath = "./data/" + cmd[3].substring(2);
            else
                rePath = "./data/" + cmd[3];

            File file = new File(rePath);
            if ((!file.exists()) || file.isDirectory())
                rePath_illegal = true;

            if (!rePath_illegal) {
                String out = GetFile(rePath);
                if (out == null)
                    return null;
                else
                    System.out.print(out);//getFile已经每句换行了，这里就不换行了}

            } else {//打印path
                if (!path.matches("^[^*<>?|\"]*$"))
                    return "Illegal path";
                if (cmd[1].charAt(0) == '.')//已经有 ./ 了
                    path = "./data/" + cmd[1].substring(2);
                else
                    path = "./data/" + cmd[1];

                file = new File(path);
                if ((!file.exists()) || file.isDirectory())
                    return "File not exists";
                String out = GetFile(path);
                if (out == null)
                    return null;
                else
                    System.out.print(out);//getFile已经每句换行了，这里就不换行了
            }
        }
        return null;
    }
}
